package go_service

import (
	"context"
	"fmt"
	"os"
)

// CreateService 创建并注册一个新的Systemd服务
//
// 参数:
//   ctx: 上下文对象，用于控制超时和取消操作
//
// 返回值:
//   error: 如果创建成功返回nil，否则返回对应的错误
//
// 示例:
//   service := NewService("nginx", "Nginx Web Server", "/usr/sbin/nginx")
//   service.Args = []string{"-g", "daemon off;"}
//   service.WorkingDir = "/etc/nginx"
//   service.AutoStart = true
//
//   ctx := context.Background()
//   if err := service.CreateService(ctx); err != nil {
//       fmt.Printf("创建服务失败: %v\n", err)
//       return
//   }
//   fmt.Println("服务创建成功")
func (s *Service) CreateService(ctx context.Context) error {
	// 验证服务配置
	if err := s.Validate(); err != nil {
		return fmt.Errorf("service configuration validation failed: %w", err)
	}

	// 检查服务是否已存在
	if s.IsServiceExist() {
		return fmt.Errorf("service %s already exists", s.Name)
	}

	// 生成服务文件
	if err := s.generateSystemdServiceFile(); err != nil {
		return fmt.Errorf("failed to create service file: %w", err)
	}

	// 重新加载Systemd配置
	if err := s.reloadSystemd(ctx); err != nil {
		return fmt.Errorf("failed to reload systemd: %w", err)
	}

	// 如果设置为开机启动，启用服务
	if s.AutoStart {
		if err := s.EnableService(ctx); err != nil {
			return fmt.Errorf("failed to enable service: %w", err)
		}
	}

	return nil
}

// RemoveService 删除一个已存在的Systemd服务
//
// 参数:
//   ctx: 上下文对象，用于控制超时和取消操作
//
// 返回值:
//   error: 如果删除成功返回nil，否则返回对应的错误
//
// 示例:
//   service := NewService("nginx", "Nginx Web Server", "/usr/sbin/nginx")
//   ctx := context.Background()
//   
//   // 先停止服务再删除
//   if err := service.Stop(ctx); err != nil {
//       fmt.Printf("停止服务失败: %v\n", err)
//   }
//   
//   if err := service.RemoveService(ctx); err != nil {
//       fmt.Printf("删除服务失败: %v\n", err)
//       return
//   }
//   fmt.Println("服务删除成功")
func (s *Service) RemoveService(ctx context.Context) error {
	// 检查服务是否存在
	if !s.IsServiceExist() {
		return fmt.Errorf("service %s does not exist", s.Name)
	}

	// 停止服务
	if s.IsRunning() {
		if err := s.Stop(ctx); err != nil {
			return fmt.Errorf("failed to stop service before removal: %w", err)
		}
	}

	// 禁用服务
	if err := s.DisableService(ctx); err != nil {
		return fmt.Errorf("failed to disable service: %w", err)
	}

	// 删除服务文件
	serviceFile := s.getServiceFilePath()
	if err := os.Remove(serviceFile); err != nil {
		return fmt.Errorf("failed to remove service file: %w", err)
	}

	// 重新加载Systemd配置
	if err := s.reloadSystemd(ctx); err != nil {
		return fmt.Errorf("failed to reload systemd after removal: %w", err)
	}

	return nil
}

// UpdateService 更新一个已存在的Systemd服务配置
//
// 参数:
//   ctx: 上下文对象，用于控制超时和取消操作
//
// 返回值:
//   error: 如果更新成功返回nil，否则返回对应的错误
//
// 示例:
//   // 获取现有服务配置
//   service := NewService("nginx", "Nginx Web Server", "/usr/sbin/nginx")
//   
//   // 修改配置
//   service.Description = "Updated Nginx Server"
//   service.Args = []string{"-g", "daemon off;", "--worker-processes", "4"}
//   service.RestartPolicy = "always"
//   
//   ctx := context.Background()
//   if err := service.UpdateService(ctx); err != nil {
//       fmt.Printf("更新服务失败: %v\n", err)
//       return
//   }
//   fmt.Println("服务更新成功")
func (s *Service) UpdateService(ctx context.Context) error {
	// 验证服务配置
	if err := s.Validate(); err != nil {
		return fmt.Errorf("service configuration validation failed: %w", err)
	}

	// 检查服务是否存在
	if !s.IsServiceExist() {
		return fmt.Errorf("service %s does not exist", s.Name)
	}

	// 停止服务
	if s.IsRunning() {
		if err := s.Stop(ctx); err != nil {
			return fmt.Errorf("failed to stop service before update: %w", err)
		}
	}

	// 重新生成服务文件
	if err := s.generateSystemdServiceFile(); err != nil {
		return fmt.Errorf("failed to update service file: %w", err)
	}

	// 重新加载Systemd配置
	if err := s.reloadSystemd(ctx); err != nil {
		return fmt.Errorf("failed to reload systemd: %w", err)
	}

	// 如果设置为开机启动，启用服务
	if s.AutoStart {
		if err := s.EnableService(ctx); err != nil {
			return fmt.Errorf("failed to enable service: %w", err)
		}
	} else {
		// 否则禁用开机启动
		if err := s.DisableService(ctx); err != nil {
			return fmt.Errorf("failed to disable service: %w", err)
		}
	}

	return nil
}
